// Tree.h: interface for the tree class.
// Copyright: (c) Project 5 Team (715), 2009
//////////////////////////////////////////////////////////////////////

// Last edited July 2012 by Zane Moser and Camille Nicodemus

#ifndef TREE_CSKETCH
#define TREE_CSKETCH

#include "TreeMain.h"
#include "Sketch.h"
#include "Geometry.h"
//#include "GeometryFunctions.h"
#include "TreeTextureLoader.h"
#include "TreeModel.h"
#include "TreeTerrain.h"

#include <math.h>
#include <string>
#include <vector>

#ifdef WIN32
	#include <time.h>
	#include <windows.h>
	#include <GL/gl.h>
	#include "GLUT/glut.h"
	
#else
	#include <OpenGL/gl.h>
	#include <GLUT/glut.h>
#endif

class CNode3D;
class CNode2D;

namespace LifeSketchTree
{
class CTree
{
public:
	CTree();
	~CTree();
	//virtual void update();
	virtual void display3D();
	//virtual float classifySketches(vector<CSketch*>* sketches);
	virtual string className();
	//virtual CSketchObject* newSketchObjectInstance();
	void regenerate();
	int leafThickness;

	//void _update();
	void _display3D();
	//void _drawTree(int midpoint);

	void setTreeMidHeight(int midHeight);
	void setSketchArea(int sketch_area_width, int sketch_area_height);

	vector<CSketch*>* sketches;	// references to the sketches representing this object
	
private:
	double _getBranchLength(CNode3D* node);
	double _getBranchLength(CNode3D* node, int numPts);
	double _getBranchRadius(CNode3D* node, int ptRadius);
	double _lineLength3D(CVec3df* p1, CVec3df* p2);
	double _lineLength(CVec2di* p1, CVec2di* p2);
	//double lineAngle(CVec2di* p1, CVec2di* p2);
	double _distToLine(CVec2di* point, CVec2di* p1, CVec2di* p2);
	CNode3D* _convert2DNodeTo3DNode(CNode2D* node);
	void _drawLeaf();
	void _drawTree3D(CNode3D* node);
	void _make3DTree();
	void _spreadBranchesOut(CNode3D* parent);
	void _discoverTree();
	void _generateFoliage();
	void _recurseTree(int sketchIndex, CNode2D* parentNode);
	void _recurseLookForFoliageIntersection(CNode2D* node, CSketch* foliage, bool insideRegion, double density, double av_distance, CVec2di* centerOfMass);
	bool _internalPoint(CVec2di* point, CVec2di* p1, CVec2di* p2);
	CVec2di* _intersectionPoint(CVec2di* q1, CVec2di* q2, CVec2di* p1, CVec2di* p2);
	bool _internalIntersectionPoint(CVec2di* q1, CVec2di* q2, CVec2di* p1, CVec2di* p2);
	CVec2di* _pointOnLine(CVec2di* p1, CVec2di* p2, double percentage);
	CVec2di* _lineEndAtAngle(CVec2di* p1, CVec2di* p2, double angle, double length);
	vector<bool> SketchFoliage;
	vector<bool> SketchesSeen;
	CNode2D* root2D;
	CNode3D* root3D;
	
	GLuint leaf_index;	

	int treeMidPoint;
	int sketch_area_width;
	int sketch_area_height;

	GLuint display_index;

	CVec3df sketch2WorldProfile(CVec2di sketchCoord);
	
};
}
#endif /* TREE_CSKETCH */